﻿namespace WebExample
{
    using System.Linq;
    using System.Web;
    using System.Web.Http;
    using System.Web.Mvc;
    using System.Web.Routing;
    using LinqToLdap;
    using LinqToLdapExtensions;
    using LinqToLdapExtensions.Domain;
    using Microsoft.Practices.Unity;
    using Microsoft.Practices.Unity.Mvc;

    /// <summary>
    /// The application.
    /// </summary>
    public class MvcApplication : HttpApplication
    {
        /// <summary>
        /// The container.
        /// </summary>
        private static IUnityContainer container;

        /// <summary>
        /// Initializes a new instance of the <see cref="MvcApplication"/> class.
        /// </summary>
        public MvcApplication()
        {
            this.BeginRequest += (sender, args) => container.Resolve<DirectoryContextUnitOfWork>().BeginUnitOfWork();
            this.EndRequest += (sender, e) => container.Resolve<DirectoryContextUnitOfWork>().EndUnitOfWork();
        }

        /// <summary>
        /// The application_ start.
        /// </summary>
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);

            container = new UnityContainer();
            
            var config = DomainSetup.SetupConfiguration();

            container.RegisterInstance<ILdapConfiguration>(config, new ContainerControlledLifetimeManager());
            
            container.RegisterType<IDirectoryContextFactory, DirectoryContextFactory>(
                new ContainerControlledLifetimeManager(), 
                new InjectionConstructor(ScopeState.WebContext, config));

            var factory = container.Resolve<IDirectoryContextFactory>();

            container.RegisterInstance(new DirectoryContextUnitOfWork(factory), new ContainerControlledLifetimeManager());

            container.RegisterInstance(container);

            FilterProviders.Providers.Remove(FilterProviders.Providers.OfType<FilterAttributeFilterProvider>().First());
            FilterProviders.Providers.Add(new UnityFilterAttributeFilterProvider(container));

            DependencyResolver.SetResolver(new UnityDependencyResolver(container));
        }
    }
}